#include "netdisk.h"

// 通过栈管理当前工作目录，支持路径的动态更新

bool is_empty(Stack_t dir){
    return dir.stackSize == 0;
}


// 用从栈中弹出目录路径
// Stack_t* dir：指向栈结构的指针
// char* del_data：用于存储被弹出的元素的数据
int pop(Stack_t* dir, char* del_data){
    if(is_empty(*dir)){
        return -1;
    }
    memcpy(del_data, dir->pTop->data, strlen(dir->pTop->data) + 1); // 把栈顶元素拷贝到del_data中
    // 出栈！！！类似链表！
    Note_t* pFree = dir->pTop;      // 栈顶结点设为要释放的结点
    dir->pTop = pFree->pnext;       // 栈顶指向下一个指针
    
    --(dir->stackSize);             // 栈大小减一

    if(dir->stackSize == 0){        // 若栈空则把栈底指针指向空
        dir->pBottom = NULL;
    }

    free(pFree->data);
    free(pFree);
    
    return 0;
}


// 将目录路径压入栈
int push(Stack_t* dir, char* add_data){
    Note_t* newNode = (Note_t*)malloc(sizeof(Note_t)); // 分配内存给新节点
    ERROR_CHECK(newNode, NULL, "malloc");    // 检查内存分配是否成功

    // 初始化结点值
    newNode->data = (char*)malloc(strlen(add_data)+1); // 分配内存给新结点的数据
    memcpy(newNode->data, add_data, strlen(add_data)); // 复制数据到新节点的data字段
    newNode->data[strlen(add_data)] = '\0'; // 确保字符串以null字符结尾
    newNode->pnext = dir->pTop; // 设置新结点的pnext指向当前的栈顶

    ++(dir->stackSize);     // 更新栈的大小
    dir->pTop = newNode;    // 更新栈顶指针pTop为新结点

    // 若更新完栈的大小为1时，同时更新栈底指针
    if(dir->stackSize == 1){
        dir->pBottom = newNode;
    }

    return 0;
}


// 遍历栈，生成当前工作目录的绝对路径
int travel_stack(Stack_t dir, char* working_dir){
    char buf1[4096] = {0};
    char target_buf[8000] = {0};
    Note_t* curr = dir.pTop;
    // 遍历栈，将每个目录项添加到target_buf中，目录项之间用/分割
    while(curr != NULL){
        sprintf(target_buf, "%s/%s", curr->data, buf1);
        memcpy(buf1, target_buf, strlen(target_buf));
        curr = curr->pnext;
    }
    // 将生成的目录复制到 working_dir
    memcpy(working_dir, target_buf, strlen(target_buf) - 1);
    working_dir[strlen(target_buf) - 1] = '\0';
    return 0;
}

int destroy_stack(Stack_t* dir){
    char del[4096] = {0};
    for(int i = 0; i < dir->stackSize; ++i){
        pop(dir, del);
    }
    bzero(dir, sizeof(*dir));
}

void print_stack(Stack_t dir){
    for(int i = 0; i < dir.stackSize; ++i){
        printf("%s\n", dir.pTop->data);
        dir.pTop = dir.pTop->pnext;
    }
}
